package com.alan.netty.test;

import com.alan.netty.util.JsonUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author weiBin
 * @date 2018/11/6
 */
public class BeanJsonMain2 {
    public static void main(String[] args) {
        Bean a1 = new Bean("{\"web\":[\"2\",\"3\"],\"app\":[\"4\"]}", "1", "test1");
        Bean a2 = new Bean("{\"web\":[\"4\"],\"app\":[]}", "2", "test2");
        Bean a3 = new Bean("{\"web\":[\"4\"],\"app\":[]}", "3", "test3");
        Bean a4 = new Bean("{\"web\":[\"5\"],\"app\":[]}", "4", "test4");
        Bean b1 = new Bean("{\"web\":[],\"app\":[\"2\",\"3\"]}", "1", "test11");
        Bean b2 = new Bean("{\"web\":[],\"app\":[\"4\"]}", "2", "test22");
        Bean b3 = new Bean("{\"web\":[],\"app\":[\"4\"]}", "3", "test33");
        Bean b4 = new Bean("{\"web\":[],\"app\":[\"5\"]}", "4", "test44");
        Map<String, List<Bean>> map = new HashMap<>();
        List<Bean> webBean = new ArrayList<>();
        List<Bean> appBean = new ArrayList<>();
        webBean.add(a1);
        webBean.add(a2);
        webBean.add(a3);
        webBean.add(a4);
        appBean.add(b1);
        appBean.add(b2);
        appBean.add(b3);
        appBean.add(b4);
        map.put("web", webBean);
        map.put("app", appBean);
        reorder(map);

        List<String> ids = new ArrayList<>();
        ids.add("2");
        ids.add("3");
//        System.out.println(map.get("app").stream().filter(e->ids.contains(e.getId())).count());
    }

    private static List<Map<String, List<Bean>>> reorder(Map<String, List<Bean>> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        List<Map<String, List<Bean>>> arr = new ArrayList<>();
        List<Bean> webList = map.get("web");
        List<Bean> appList = map.get("app");
        if (webList == null) {
            webList = new ArrayList<>();
        }
        if (appList == null) {
            appList = new ArrayList<>();
        }
        while (webList.size() > 0 || appList.size() > 0) {
            System.out.println("------------------------------------");
            Bean temp = null;
            Map<String, List<Integer>> childIdMap = new HashMap<>();
            //类型 0 web 1 app
            int type = 0;
            if (webList.size() > 0) {
                temp = webList.get(0);
                List<Integer> childIdList = new ArrayList<>();
                childIdList.add(Integer.valueOf(temp.getId()));
                childIdMap.put("web", childIdList);
                childIdMap.put("app", new ArrayList<>());
                type = 0;
            } else if (appList.size() > 0) {
                temp = appList.get(0);
                List<Integer> childIdList = new ArrayList<>();
                childIdList.add(Integer.valueOf(temp.getId()));
                childIdMap.put("web", new ArrayList<>());
                childIdMap.put("app", childIdList);
                type = 1;
            } else {
                //没有数据了
                break;
            }
            Map<String, List<Bean>> result = getNonFollow(map);
            arr.add(result);
            webList.removeAll(result.get("web"));
            appList.removeAll(result.get("app"));
            map.put("web", webList);
            map.put("app", appList);
        }
        for (int i = 0; i < arr.size(); i++) {
            Map<String, List<Bean>> temp = arr.get(i);
            for (String key : temp.keySet()) {
                int finalIndex = i + 1;
                temp.get(key).forEach(e -> {
                    System.out.println(String.format("index %s: type %s Bean id is %s", finalIndex, key, e.getId()));
                });
            }
        }
        return arr;
    }

    /**
     * @param map
     * @return
     */
    private static Map<String, List<Bean>> getNonFollow(Map<String, List<Bean>> map) {
        Map<String, List<Bean>> result = new ConcurrentHashMap<>();
        List<Bean> webResult = new ArrayList<>();
        List<Bean> appResult = new ArrayList<>();
        result.put("web", webResult);
        result.put("app", appResult);
        if (null == map || map.size() == 0) {
            return null;
        }
        List<Bean> webList = map.get("web");
        List<Bean> appList = map.get("app");
        webResult = getList(webList, appList, 0);
        appResult = getList(webList, appList, 1);
        result.put("web", webResult);
        result.put("app", appResult);
        return result;
    }

    private static List<Bean> getList(List<Bean> list1, List<Bean> list2, int type) {
        List<Bean> result = new ArrayList<>();
        for (Bean bean : list1) {
            String follow = bean.getFollowIds();
            if (StringUtils.isEmpty(follow)) {
                result.add(bean);
            } else {
                Map object = null;
                try {
                    object = JsonUtil.toObject(bean.getFollowIds(), Map.class);
                    //解析依赖的id集合
                    List<String> webIds = Arrays.asList(JSONObject.parseArray(object.get("web").toString()).toArray()).stream().map(e -> String.valueOf(e)).collect(Collectors.toList());
                    List<String> appIds = Arrays.asList(JSONObject.parseArray(object.get("app").toString()).toArray()).stream().map(e -> String.valueOf(e)).collect(Collectors.toList());
                    if (type == 1) {
                        if (list1.stream().filter(e -> webIds.contains(e.getId())).count() > 0 || list2.stream().filter(e -> appIds.contains(e.getId())).count() > 0) {
                            continue;
                        } else {
                            result.add(bean);
                        }
                    } else if (type == 0) {
                        if (list1.stream().filter(e -> appIds.contains(e.getId())).count() > 0 || list2.stream().filter(e -> webIds.contains(e.getId())).count() > 0) {
                            continue;
                        } else {
                            result.add(bean );
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e.getMessage());
                }
            }
        }
        return result;
    }
}

